package com.usian.order.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.json.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.usian.entity.*;
import com.usian.order.alipay.AliPayProperties;
import com.usian.order.feign.CarFeignClient;
import com.usian.order.mapper.FavoritesMapper;
import com.usian.order.mapper.NotificationsMapper;
import com.usian.order.mapper.PaymentMethodsMapper;
import com.usian.order.mapper.PaymentRecordsMapper;
import com.usian.order.service.IOrdersService;
import jakarta.annotation.Resource;
import jakarta.el.LambdaExpression;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/order/alipay")
public class AlipayController {

    // 支付宝沙箱网关地址
    private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String FORMAT = "JSON";
    private static final String CHARSET = "UTF-8";
    //签名方式
    private static final String SIGN_TYPE = "RSA2";

    @Resource
    private AliPayProperties aliPayConfig;

    @Resource
    private IOrdersService ordersService;
    @Autowired
    private PaymentMethodsMapper paymentMethodsMapper;

    @Autowired
    private PaymentRecordsMapper paymentRecordsMapper;

    @Autowired
    private NotificationsMapper notificationsMapper;

    @Autowired
    private CarFeignClient carFeignClient;

    @GetMapping("/pay")  //  /alipay/pay?orderNo=xxx
    public void pay(String orderId, @RequestParam String radio,@RequestParam String nickName, HttpServletResponse httpResponse) throws Exception {
        // 查询订单信息
        Orders orders = ordersService.selectByOrderNo(orderId);
        // 如果订单不存在，则终止执行
        if (orders == null) {
            return;
        }
        // 输出支付方式的选择
        System.out.println("支付方式：" +radio );

        // 创建一个支付方式对象
        PaymentMethods paymentMethods = new PaymentMethods();

        // 根据用户选择的支付方式设置PaymentMethods对象的属性
        if(radio.equals("1")){
            // 设置支付宝支付方式
            paymentMethods.setPaymentType("wechat_pay");
            paymentMethods.setUserId(orders.getUserId());
            paymentMethods.setIsDefault(true);
            paymentMethods.setCardholderName(null);
            paymentMethods.setCreditCardNumber(null);
        } else if(radio.equals("2")){
            // 设置微信支付方式
            paymentMethods.setPaymentType("alipay");
            paymentMethods.setUserId(orders.getUserId());
            paymentMethods.setIsDefault(true);
            paymentMethods.setCardholderName(null);
            paymentMethods.setCreditCardNumber(null);
        } else if(radio.equals("3")){
            // 设置银行卡支付方式
            paymentMethods.setPaymentType("credit_card");
            paymentMethods.setUserId(orders.getUserId());
            paymentMethods.setIsDefault(true);
            paymentMethods.setCardholderName(nickName);
            paymentMethods.setCreditCardNumber(String.valueOf(10086));
        }

        // 将PaymentMethods对象插入到数据库中
        paymentMethodsMapper.insert(paymentMethods);

        // 创建一个支付记录对象
        PaymentRecords paymentRecords = new PaymentRecords();
        // 设置支付记录的属性
        paymentRecords.setOrderId(orders.getOrderId());
        paymentRecords.setPaymentMethodId(paymentMethods.getPaymentMethodId());
        paymentRecords.setPaymentAmount(orders.getTotalPrice());
        paymentRecords.setPaymentTime(new DateTime().toLocalDateTime());

        // 将PaymentRecords对象插入到数据库中
        paymentRecordsMapper.insert(paymentRecords);


        // 1. 创建Client，通用SDK提供的Client，负责调用支付宝的API
        AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
                aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);



        // 2. 创建 Request并设置Request参数
        AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();  // 发送请求的 Request类
        request.setNotifyUrl(aliPayConfig.getNotifyUrl());
        System.out.println("------------------------"+aliPayConfig.getNotifyUrl());

        JSONObject bizContent = new JSONObject();
        bizContent.set("out_trade_no", orders.getOrderId());  // 我们自己生成的订单编号
        bizContent.set("total_amount", orders.getTotalPrice()); // 订单的总金额
        Orders byId = ordersService.getById(orders.getCarId());
        if(byId==null){
            return;
        }
        Cars data = carFeignClient.getCarByCarId(byId.getCarId()).getData();
        if(data==null){
            return;
        }
        bizContent.set("subject", data.getCarModel());
        bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY");  // 固定配置
        request.setBizContent(bizContent.toString());
        request.setReturnUrl("http://localhost:8080/#/reserve"); // 支付完成后自动跳转到本地页面的路径
        // 执行请求，拿到响应的结果，返回给浏览器
        String form = "";
        try {
            form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        httpResponse.setContentType("text/html;charset=" + CHARSET);
        httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
        httpResponse.getWriter().flush();
        httpResponse.getWriter().close();
    }
    private static final Logger logger = LoggerFactory.getLogger(AlipayController.class);
    @ExceptionHandler(Exception.class)
    public void handleException(Exception e) {
        logger.error("An exception occurred in payNotify method", e);
    }

    @PostMapping("/notify")  // 注意这里必须是POST接口
    public void payNotify(HttpServletRequest request) throws Exception {
        if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
            System.out.println("=========支付宝异步回调========");

            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String name : requestParams.keySet()) {
                params.put(name, request.getParameter(name));
            }

            String sign = params.get("sign");
            String content = AlipaySignature.getSignCheckContentV1(params);
            boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, aliPayConfig.getAlipayPublicKey(), "UTF-8"); // 验证签名
            // 支付宝验签
            if (checkSignature) {
                // 验签通过
                System.out.println("交易名称: " + params.get("subject"));
                System.out.println("交易状态: " + params.get("trade_status"));
                System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
                System.out.println("商户订单号: " + params.get("out_trade_no"));
                System.out.println("交易金额: " + params.get("total_amount"));
                System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
                System.out.println("买家付款时间: " + params.get("gmt_payment"));
                System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));


                String tradeNo = params.get("out_trade_no");
                // 更新订单状态为已支付，设置支付信息
                System.out.println("tradeNo-------------------------------------------------------:"+tradeNo);
                Orders orders = ordersService.selectByOrderNo(tradeNo);
                Notifications notifications = new Notifications();
                notifications.setUserId(orders.getUserId());
                notifications.setCarId(orders.getCarId());
                notifications.setMessageText("您已成功支付订单");
                notifications.setCreatedAt(new DateTime().toLocalDateTime());
                notificationsMapper.insert(notifications);
                orders.setOrderStatus("已支付");
                ordersService.updateById(orders);
            }
        }
    }
}
